package utils

import (
	"crypto/md5"
	"fmt"
	"github.com/golang-jwt/jwt/v4"
	"github.com/sirupsen/logrus"
	"my-desktop/config"
	"my-desktop/models"
	"strings"
	"time"
)

type MyCustomClaims struct {
	UserName string `json:"userName"`
	Password string `json:"password"`
	UserID   uint64 `json:"userID"`
	jwt.RegisteredClaims
}

// md5
// str 需要编码的内容
// salt 盐
func Md5Encode(str string, salt ...interface{}) (encodeStr string) {
	if l := len(salt); l > 0 {
		slice := make([]string, l+1)
		str = fmt.Sprintf(str+strings.Join(slice, "%v"), salt...)
	}
	return fmt.Sprintf("%x", md5.Sum([]byte(str)))
}

func GetToken(user *models.SysUser) (resToken string) {
	secret := config.Jwt.Secret

	claims := &MyCustomClaims{
		user.UserName,
		user.Password,
		user.UserID,
		jwt.RegisteredClaims{
			// A usual scenario is to set the expiration time relative to the current time
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(2 * time.Hour)),
			Issuer:    "union",
			Subject:   "user",
			ID:        string(user.UserID),
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	resToken, err := token.SignedString([]byte(secret))
	if err != nil {
		logrus.Error("token生生成失败")
		return ""
	}
	return resToken
}

func ParseToken(tokenString string) (user *models.SysUser, err error) {
	secret := config.Jwt.Secret

	token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(secret), nil
	})

	if err != nil {
		return nil, err
	}

	user = &models.SysUser{}
	if claims, ok := token.Claims.(*MyCustomClaims); ok && token.Valid {
		user.UserName = claims.UserName
		user.Password = claims.Password
		user.UserID = claims.UserID
		return user, nil
	} else {
		logrus.Error("token生解析失败")
		return nil, err
	}
}
